﻿/************************************************************************

   Extended Silverlight Toolkit

   Copyright (C) 2010-2012 Xceed Software Inc.

   This program is provided to you under the terms of the Microsoft Public
   License (Ms-PL) as published at http://extendedsilverlight.codeplex.com/license

   Please purchase a commercial version of this toolkit if you are using
   it in a commercial product. The commercial versions support the project,
   and also include more features for each control, priority support,
   source code, updates, removed watermark, and a proprietary license.

   Visit http://xceed.com and follow @datagrid on Twitter.

  **********************************************************************/

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows.Markup;

namespace Xceed.Silverlight.Data
{
  [DebuggerDisplay( "FilterBy = {DebuggerDisplayString}" )]
  [ContentProperty( "ChildExpressions" )]
  public abstract class FilterExpressionOperator : FilterExpressionBase
  {
    #region Constructors

    internal FilterExpressionOperator( params FilterExpressionBase[] expressions )
      : this( ( IEnumerable<FilterExpressionBase> )expressions )
    {
    }

    internal FilterExpressionOperator( IEnumerable<FilterExpressionBase> expressions )
      : this()
    {
      if( expressions != null )
      {
        foreach( FilterExpressionBase filterExpression in expressions )
        {
          m_childExpressions.InternalAdd( filterExpression );
        }
      }
    }

    internal FilterExpressionOperator()
    {
      m_childExpressions = new FilterExpressionCollection( this );
    }

    #endregion

    #region ChildExpressions Property

    public FilterExpressionCollection ChildExpressions
    {
      get
      {
        return m_childExpressions;
      }
    }

    private FilterExpressionCollection m_childExpressions; //null

    #endregion

    public override int GetHashCode()
    {
#if WINDOWS_PHONE
      this.Freeze();
#endif

      return this.GetType().GetHashCode();
    }

    public override bool Equals( object obj )
    {
#if WINDOWS_PHONE
      this.Freeze();
#endif

      if( object.ReferenceEquals( this, obj ) )
        return true;

      FilterExpressionOperator expression = obj as FilterExpressionOperator;
      if( expression == null )
        return false;

      if( expression.GetHashCode() != this.GetHashCode() )
        return false;

      if( expression.ChildExpressions.Count != this.ChildExpressions.Count )
        return false;

      return this.ChildExpressions.SequenceEqual( expression.ChildExpressions );
    }

    public void Add( FilterExpressionBase expression )
    {
      if( this.IsFrozen )
        throw new InvalidOperationException( "An attempt was made to modify a FilterExpressionOperator that has been frozen" );

      if( expression != null )
      {
        Debug.Assert(
          !object.ReferenceEquals( expression, this ),
          "Cannot add self." );

        if( !m_childExpressions.Contains( expression ) )
        {
          m_childExpressions.InternalAdd( expression );
        }
      }
    }

    internal override void FreezeOverride()
    {
      if( m_childExpressions.Count < 2 )
        throw new InvalidOperationException( this.GetType().Name + " requires at least two child expressions to be valid." );

      foreach( FilterExpressionBase child in m_childExpressions )
      {
        child.Freeze();
      }

      base.FreezeOverride();
    }
  }
}
